package com.company.project.core.aop;


import com.company.project.core.exception.BusinessException;
import com.company.project.core.support.ErrorCode;
import com.company.project.core.support.ErrorResult;
import com.company.project.core.support.Result;
import com.company.project.utils.StringUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.multipart.MultipartException;

import javax.servlet.http.HttpServletRequest;
import java.io.ByteArrayOutputStream;
import java.io.PrintStream;
import java.util.Iterator;

@RestControllerAdvice
public class GlobalExceptionHandler {
    private static final Logger logger = LoggerFactory.getLogger(GlobalExceptionHandler.class);
    // 对这个异常的统一处理，返回值 和Controller的返回规则一样
    @ExceptionHandler(value = MultipartException.class)
    public Result handleMultipartException(MultipartException e) {
        String message = "文件超过最大限制:";
        logger.error(message,e);
        return new ErrorResult(ErrorCode.INTERNAL_SERVER_ERROR.code(), message + e.getLocalizedMessage());
    }

    @ExceptionHandler(value = Exception.class)
    public Result jsonErrorHandler(HttpServletRequest req, Exception e) {
        String uri = req.getRequestURL().toString();
        String message = "请求[" + uri + "]时系统出错！";
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        e.printStackTrace(new PrintStream(baos));
        String exception = baos.toString();
        logger.error(e.toString() + "result>>" + exception);
        return new ErrorResult(ErrorCode.INTERNAL_SERVER_ERROR.code(), message + e.getLocalizedMessage());
    }

    /**
     * 处理'@Valid'注解验证实体出错
     * @param e MethodArgumentNotValidException
     * @return  错误提示
     */
    @ExceptionHandler(value = MethodArgumentNotValidException.class)
    public ErrorResult handleMethodArgumentNotValidException(MethodArgumentNotValidException e) {
        BindingResult result = e.getBindingResult();
        StringBuilder sb = new StringBuilder();
        for (Iterator<FieldError> it = result.getFieldErrors().iterator(); it.hasNext();) {
            FieldError fieldError = it.next();
            sb.append(fieldError.getField());
            sb.append(fieldError.getDefaultMessage());
            if (it.hasNext()) {
                sb.append(";");
            }
        }
        logger.error(e.toString()+"result>>"+sb.toString());
        return new ErrorResult(ErrorCode.VALID_NOT_PASS.code(), sb.toString());
    }

    /**
     * 自定义异常通用处理方式
     * @param e
     * @return
     */
    @ExceptionHandler(value = BusinessException.class)
    public ErrorResult handleApiException(BusinessException e) {
        String message = e.getMessage();
        int code = e.getHttpCode().code();
        logger.error(e.toString() + "result>>errorCode=" + code);
        if (StringUtil.isEmpty(message)) {
            return new ErrorResult(e.getHttpCode());
        }
        return new ErrorResult(code, message);
    }
}

